package com.dashu.core.service;

import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.enums.common.GroupType;
import com.dashu.base.enums.common.PersonalType;
import com.dashu.base.enums.school.TeacherType;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.core.dto.attendance.AttendanceRuleDTO;
import com.dashu.core.dto.attendance.AttendanceGroupDTO;
import com.dashu.core.handler.VerificationException;
import com.dashu.core.model.AttendanceGroup;
import com.dashu.core.model.QAttendanceGroup;
import com.dashu.core.vo.attendancek.AttendanceGroupVO;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class AttendanceGroupService extends DataService {
    @Autowired
    private CompanyService companyService;
    @Autowired
    private CompanyDepartmentService companyDepartmentService;
    @Autowired
    private CompanyClsService companyClsService;
    @Autowired
    private CompanyTeacherService companyTeacherService;
    @Autowired
    private CompanyPersonalService companyPersonalService;

    @Transactional(value = Transactional.TxType.REQUIRES_NEW)
    public AttendanceGroupDTO add(AttendanceGroupVO attendanceGroupVO) {
        AttendanceGroup attendanceGroup = CopyUtil.copyEnty(attendanceGroupVO, AttendanceGroup.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            if (attendanceGroupVO.getId() == 0)
                attendanceGroup.setId(UIDUtil.nextId());
            if (attendanceGroupVO.getCreateUser() == 0)
                attendanceGroup.setCreateUser(userId);
            if (attendanceGroupVO.getCreateTime() == 0)
                attendanceGroup.setCreateTime(System.currentTimeMillis());

            attendanceGroup.setGroupName(attendanceGroupVO.getGroupName());
            attendanceGroup.setGId(attendanceGroupVO.getGId());
            attendanceGroup.setRuleId(attendanceGroupVO.getRuleId());
            if (attendanceGroupVO.getRuleType().equals("TEACHER")) {
                attendanceGroup.setGroupType(attendanceGroupVO.getGroupType());
                if (attendanceGroupVO.getGroupType().equals("PERSONAL")) {
                    companyTeacherService.updataAttendance(attendanceGroupVO.getGId(), attendanceGroupVO.getRuleId());
                } else {
                    TeacherType teacherTypes = TeacherType.map.get(attendanceGroupVO.getGroupType());
                    //教师类型没有gid
                    companyTeacherService.updataAttendanceCompany(attendanceGroupVO.getAtBaseId(), attendanceGroupVO.getRuleId(), teacherTypes);
                }
            } else {
                attendanceGroup.setGroupType(GroupType.map.get(attendanceGroupVO.getGroupType()).name());
                List<PersonalType> personalTypes = CopyUtil.copyList(Arrays.asList(attendanceGroupVO.getRuleInType().split(",")), PersonalType.class);
                if (GroupType.COMPANY.name().equals(attendanceGroupVO.getGroupType()))
                    companyPersonalService.updataAttendanceCompany(attendanceGroupVO.getGId(), attendanceGroupVO.getRuleId(), personalTypes);
                if (GroupType.DEPARTMENT.name().equals(attendanceGroupVO.getGroupType()))
                    companyPersonalService.updataAttendanceDepartment(attendanceGroupVO.getGId(), attendanceGroupVO.getRuleId(), personalTypes);
                if (GroupType.CLS.name().equals(attendanceGroupVO.getGroupType()))
                    companyPersonalService.updataAttendanceCls(attendanceGroupVO.getGId(), attendanceGroupVO.getRuleId(), personalTypes);
                if (GroupType.PERSONAL.name().equals(attendanceGroupVO.getGroupType()))
                    companyPersonalService.updataAttendancePersonal(attendanceGroupVO.getGId(), attendanceGroupVO.getRuleId());
            }
            entityManager.persist(attendanceGroup);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        AttendanceGroupDTO attendanceGroupDTO = CopyUtil.copyEnty(attendanceGroup, AttendanceGroupDTO.class);
        return attendanceGroupDTO;
    }

    @Transactional
    public boolean deleteAttendanceGroup(long attendancekRuleId, String ruleType, String ruleInType) throws Exception {
        QAttendanceGroup qAttendanceGroup = QAttendanceGroup.attendanceGroup;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qAttendanceGroup.ruleId.eq(attendancekRuleId));
        List<AttendanceGroup> attendanceGroups =
                queryFactory
                        .select(qAttendanceGroup)
                        .from(qAttendanceGroup)
                        .where(booleanBuilder.getValue())
                        .fetch();
        for (AttendanceGroup ag : attendanceGroups) {
            try {
                if (ruleType.equals("TEACHER")) {
                    if (ag.getGroupType().equals("PERSONAL")) {
                        companyTeacherService.updataAttendance(ag.getGId(), 0);
                    } else {
                        TeacherType teacherTypes = TeacherType.map.get(ag.getGroupType());
                        companyTeacherService.findByCompanieId(ag.getGId()).stream().forEach(ct -> {
                            try {
                                companyTeacherService.updataAttendanceCompany(ct.getId(), 0, teacherTypes);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });

                    }
                } else {
                    List<PersonalType> personalTypes = CopyUtil.copyList(Arrays.asList(ruleInType.split(",")), PersonalType.class);
                    if (GroupType.COMPANY.name().equals(ag.getGroupType())) {
                        companyPersonalService.updataAttendanceCompany(ag.getGId(), 0, personalTypes);
                        if (GroupType.DEPARTMENT.name().equals(ag.getGroupType()))
                            companyPersonalService.updataAttendanceDepartment(ag.getGId(), 0, personalTypes);
                        if (GroupType.CLS.name().equals(ag.getGroupType()))
                            companyPersonalService.updataAttendanceCls(ag.getGId(), 0, personalTypes);
                        if (GroupType.PERSONAL.name().equals(ag.getGroupType()))
                            companyPersonalService.updataAttendancePersonal(ag.getGId(), 0);
                    }
                    entityManager.remove(ag);
//            entityManager.flush();
                    entityManager.setFlushMode(FlushModeType.AUTO);
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Transactional
    public boolean updataAttendanceGroup(List<AttendanceGroupVO> attendanceGroupVOS, long attendancekRuleId, String ruleType, String ruleInType) throws Exception {
        deleteAttendanceGroup(attendancekRuleId, ruleType, ruleInType);
        long userId = Long.parseLong(VerificationUtil.getUserId());
        attendanceGroupVOS.stream().forEach(ag -> {
            ag.setRuleType(ruleInType);
            ag.setRuleInType(ruleInType);
            ag.setCreateTime(new Date().getTime());
            ag.setUpdateUser(userId);
            add(ag);
        });
        return true;

    }


    public List<AttendanceGroupDTO> findAttendanceGroup(long attendancekRuleId) {
        QAttendanceGroup qAttendanceGroup = QAttendanceGroup.attendanceGroup;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qAttendanceGroup.ruleId.eq(attendancekRuleId));
        List<AttendanceGroup> attendanceGroups =
                queryFactory
                        .select(qAttendanceGroup)
                        .from(qAttendanceGroup)
                        .where(booleanBuilder.getValue())
                        .fetch();
        List<AttendanceGroupDTO> attendanceGroupDTOS = CopyUtil.copyList(attendanceGroups, AttendanceGroupDTO.class);
        return attendanceGroupDTOS;

    }

}
